package com.xyht.sca_s.student_manage_system.modules.student.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xyht.sca_s.student_manage_system.auth.entity.Node;
import com.xyht.sca_s.student_manage_system.common.commonReturn.CommonCodeEnum;
import com.xyht.sca_s.student_manage_system.common.commonReturn.CommonResult;
import com.xyht.sca_s.student_manage_system.common.commonReturn.ExceptionCast;
import com.xyht.sca_s.student_manage_system.common.commonReturn.ResponseResult;
import com.xyht.sca_s.student_manage_system.common.util.ApiModelUtil;
import com.xyht.sca_s.student_manage_system.common.util.CacheUtil;
import com.xyht.sca_s.student_manage_system.common.util.QrUtil;
import com.xyht.sca_s.student_manage_system.common.util.TimeUtil;
import com.xyht.sca_s.student_manage_system.modules.common.entity.SmsImportTask;
import com.xyht.sca_s.student_manage_system.modules.common.entity.SmsImportTaskDetail;
import com.xyht.sca_s.student_manage_system.modules.common.mapper.SmsImportTaskDetailMapper;
import com.xyht.sca_s.student_manage_system.modules.common.mapper.SmsImportTaskMapper;
import com.xyht.sca_s.student_manage_system.modules.org.entity.OrgNode;
import com.xyht.sca_s.student_manage_system.modules.org.entity.SmsOrgStructure;
import com.xyht.sca_s.student_manage_system.modules.org.entity.SmsOrgUserRelation;
import com.xyht.sca_s.student_manage_system.modules.org.entity.resp.SmsOrgStructureResp;
import com.xyht.sca_s.student_manage_system.modules.org.mapper.SmsOrgStructureMapper;
import com.xyht.sca_s.student_manage_system.modules.org.mapper.SmsOrgUserRelationMapper;
import com.xyht.sca_s.student_manage_system.modules.org.service.SmsOrgUserRelationService;
import com.xyht.sca_s.student_manage_system.modules.org.util.NodeTreeUtil;
import com.xyht.sca_s.student_manage_system.modules.org.util.NodeUtil;
import com.xyht.sca_s.student_manage_system.modules.student.entity.SmsStudentInfo;
import com.xyht.sca_s.student_manage_system.modules.student.entity.SmsUserStudentRelation;
import com.xyht.sca_s.student_manage_system.modules.student.entity.req.SmsStudentExportReq;
import com.xyht.sca_s.student_manage_system.modules.student.entity.req.SmsStudentInfoReq;
import com.xyht.sca_s.student_manage_system.modules.student.entity.req.SmsStudentParentInfoReq;
import com.xyht.sca_s.student_manage_system.modules.student.entity.resp.SmsStudentInfoResp;
import com.xyht.sca_s.student_manage_system.modules.student.entity.resp.SmsStudentInfoSimpleResp;
import com.xyht.sca_s.student_manage_system.modules.student.entity.resp.SmsStudentParentInfoResp;
import com.xyht.sca_s.student_manage_system.modules.student.mapper.SmsStudentInfoMapper;
import com.xyht.sca_s.student_manage_system.modules.student.mapper.SmsUserStudentRelationMapper;
import com.xyht.sca_s.student_manage_system.modules.student.service.SmsStudentInfoService;
import com.xyht.sca_s.student_manage_system.modules.teacher.mapper.SmsTeacherInfoMapper;
import com.xyht.sca_s.student_manage_system.modules.teacher.mapper.SmsUserTeacherRelationMapper;
import com.xyht.sca_s.student_manage_system.modules.user.entity.SmsUser;
import com.xyht.sca_s.student_manage_system.modules.user.entity.SmsUserRoleRelation;
import com.xyht.sca_s.student_manage_system.modules.user.mapper.SmsRoleMapper;
import com.xyht.sca_s.student_manage_system.modules.user.mapper.SmsUserMapper;
import com.xyht.sca_s.student_manage_system.modules.user.mapper.SmsUserRoleRelationMapper;
import freemarker.template.Configuration;
import freemarker.template.Template;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedWriter;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Future;
import java.util.stream.Collectors;

import static com.xyht.sca_s.student_manage_system.common.util.ParamCheckUtil.isNullOrEmpty;
import static com.xyht.sca_s.student_manage_system.modules.common.constant.TaskDetailReason.*;
import static com.xyht.sca_s.student_manage_system.modules.common.constant.TaskNameExample.TASK_NAME_STUDENT_INFO_IMPORT;
import static com.xyht.sca_s.student_manage_system.modules.common.constant.TaskStatus.TASK_STATUS_DONE;
import static com.xyht.sca_s.student_manage_system.modules.common.constant.TaskStatus.TASK_STATUS_ERR;
import static com.xyht.sca_s.student_manage_system.modules.common.constant.TaskTypeConstant.TASK_TYPE_ASSET_STUDENT_INFO;
import static com.xyht.sca_s.student_manage_system.modules.org.constants.OrgNameConstant.ORG_NAME_COLLAGE;
import static com.xyht.sca_s.student_manage_system.modules.org.constants.OrgTypeConstant.*;
import static com.xyht.sca_s.student_manage_system.modules.student.constant.StudentInfoCommonConstant.PER_SHEET_NUM;
import static com.xyht.sca_s.student_manage_system.modules.student.constant.StudentStatus.*;
import static com.xyht.sca_s.student_manage_system.modules.user.constant.DefaultRole.ROLE_STUDENT;
import static com.xyht.sca_s.student_manage_system.modules.user.constant.TeacherAndStudentFlag.STUDENT_FLAG;
import static com.xyht.sca_s.student_manage_system.modules.user.constant.commonConstant.DEFAULT_PASSWORD;

/**
 * <p>
 * 学生学籍信息表 服务实现类
 * </p>
 *
 * @author XYHT
 * @since 2022-12-03
 */
@Service
public class SmsStudentInfoServiceImpl extends ServiceImpl<SmsStudentInfoMapper, SmsStudentInfo> implements SmsStudentInfoService {
    @Autowired
    private SmsOrgStructureMapper smsOrgStructureMapper;
    @Autowired
    private SmsImportTaskMapper smsImportTaskMapper;
    @Autowired
    private SmsImportTaskDetailMapper smsImportTaskDetailMapper;

    @Autowired
    private SmsTeacherInfoMapper smsTeacherInfoMapper;
    @Autowired
    private SmsUserTeacherRelationMapper smsUserTeacherRelationMapper;
    @Autowired
    private SmsStudentInfoMapper smsStudentInfoMapper;
    @Autowired
    private SmsUserStudentRelationMapper smsUserStudentRelationMapper;
    @Autowired
    private SmsOrgUserRelationMapper smsOrgUserRelationMapper;
    @Autowired
    private SmsOrgUserRelationService smsOrgUserRelationService;
    @Autowired
    private SmsUserMapper smsUserMapper;
    @Autowired
    private SmsRoleMapper smsRoleMapper;
    @Autowired
    private SmsUserRoleRelationMapper smsUserRoleRelationMapper;
    @Autowired
    private ApiModelUtil apiModelUtil;

    @Autowired
    private CacheUtil cacheUtil;

    @Autowired
    private NodeTreeUtil nodeTreeUtil;


    @Override
    @Async
    public Future<ResponseResult> batchImportStudentInfo(Map<String, Object> map, String user_id) {
        JSONObject jsonObject = JSONObject.parseObject(JSON.toJSONString(map));
        SmsImportTask smsImportTask;
        List<SmsStudentInfo> studentInfoList = JSONObject.parseArray(JSON.toJSONString(jsonObject.get("list")), SmsStudentInfo.class);
        if (studentInfoList == null || studentInfoList.size() < 1) {
            return new AsyncResult<>(CommonResult.failed(CommonCodeEnum.INVALID_PARAM));
        }
        //创建导入任务
        smsImportTask = new SmsImportTask();
        smsImportTask.setTaskName(TASK_NAME_STUDENT_INFO_IMPORT);
        smsImportTask.setUserId(user_id);
        smsImportTask.setTaskType(TASK_TYPE_ASSET_STUDENT_INFO);
        smsImportTaskMapper.insert(smsImportTask);

        batchAddStudentInfo(studentInfoList, smsImportTask.getId());
        return new AsyncResult<>(CommonResult.success());
    }

    @Resource
    PlatformTransactionManager transactionManager;

    private void batchAddStudentInfo(List<SmsStudentInfo> list, String task_id) {
        int OFFSET_ROW = 1;
        int task_status = TASK_STATUS_DONE;
        for (int i = 0; i < list.size(); i++) {
            //开启事务
            DefaultTransactionDefinition dt = new DefaultTransactionDefinition();
            // 嵌套事务 PROPAGATION_REQUIRES_NEW 每次开启一个新的事务
            dt.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
            // 设置嵌套事务
            TransactionStatus status = transactionManager.getTransaction(dt);
            SmsStudentInfo smsStudentInfo = list.get(i);
            try {
                List<Integer> orgIdList = new ArrayList<>();
                //必填字段验证
                if (isNullOrEmpty(smsStudentInfo.getStuNo()) || isNullOrEmpty(smsStudentInfo.getStuName()) || isNullOrEmpty(smsStudentInfo.getStuTel())) {
                    transactionManager.rollback(status);
                    createTeacherImportTaskDetail(smsStudentInfo.getStuNo(), smsStudentInfo.getStuName(), task_id, REASON_INVALID_PARAM, (i + OFFSET_ROW) + "");
                    task_status = TASK_STATUS_ERR;
                    continue;
                }
                if (isNullOrEmpty(smsStudentInfo.getStuCollege()) || isNullOrEmpty(smsStudentInfo.getStuMajor())
                        || isNullOrEmpty(smsStudentInfo.getStuGrade()) || isNullOrEmpty(smsStudentInfo.getStuClass())) {
                    transactionManager.rollback(status);
                    createTeacherImportTaskDetail(smsStudentInfo.getStuNo(), smsStudentInfo.getStuName(), task_id, REASON_INVALID_PARAM, (i + OFFSET_ROW) + "");
                    task_status = TASK_STATUS_ERR;
                    continue;
                }

                QueryWrapper<SmsOrgStructure> orgWrapper = new QueryWrapper<>();
                List<SmsOrgStructure> orgList = smsOrgStructureMapper.selectList(orgWrapper);
                orgWrapper.lambda().eq(SmsOrgStructure::getOrgName, smsStudentInfo.getStuCollege());
                SmsOrgStructure collegeOrg = smsOrgStructureMapper.selectOne(orgWrapper);
                if (collegeOrg == null) {
                    transactionManager.rollback(status);
                    createTeacherImportTaskDetail(smsStudentInfo.getStuNo(), smsStudentInfo.getStuName(), task_id, REASON_ORG_COLLEGE_NOT_EXIST, (i + OFFSET_ROW) + "");
                    task_status = TASK_STATUS_ERR;
                    continue;
                }
                List<Node> nodeList = new ArrayList<>();
                for (SmsOrgStructure structure : orgList) {
                    Node node = new Node();
                    BeanUtils.copyProperties(structure, node);
                    nodeList.add(node);
                }
                Node collegeNode = nodeTreeUtil.getChildNodesTree(nodeList, collegeOrg.getId());
                List<Node> childNode = collegeNode.getChildNodeList();
                List<Node> majorNode = childNode.stream()
                        .filter(node -> node.getOrgName().equals(smsStudentInfo.getStuMajor()))
                        .collect(Collectors.toList());
                if (majorNode.size() < 1) {
                    transactionManager.rollback(status);
                    createTeacherImportTaskDetail(smsStudentInfo.getStuNo(), smsStudentInfo.getStuName(), task_id, REASON_ORG_MAJOR_NOT_EXIST, (i + OFFSET_ROW) + "");
                    task_status = TASK_STATUS_ERR;
                    continue;
                }
                List<Node> gradeNode = majorNode.get(0).getChildNodeList().stream()
                        .filter(node -> node.getOrgName().equals(smsStudentInfo.getStuGrade()))
                        .collect(Collectors.toList());
                if (gradeNode.size() < 1) {
                    transactionManager.rollback(status);
                    createTeacherImportTaskDetail(smsStudentInfo.getStuNo(), smsStudentInfo.getStuName(), task_id, REASON_ORG_GRADE_NOT_EXIST, (i + OFFSET_ROW) + "");
                    task_status = TASK_STATUS_ERR;
                    continue;
                }
                List<Node> classNode = gradeNode.get(0).getChildNodeList().stream()
                        .filter(node -> node.getOrgName().equals(smsStudentInfo.getStuClass()))
                        .collect(Collectors.toList());
                if (classNode.size() < 1) {
                    transactionManager.rollback(status);
                    createTeacherImportTaskDetail(smsStudentInfo.getStuNo(), smsStudentInfo.getStuName(), task_id, REASON_ORG_CLASS_NOT_EXIST, (i + OFFSET_ROW) + "");
                    task_status = TASK_STATUS_ERR;
                    continue;
                }
                orgIdList.add(classNode.get(0).getId());

                String student_id;
                String user_id;

                //工号验证 学生更新 添加
                boolean update_add_flag = true;  //true为添加  false为更新
                QueryWrapper<SmsStudentInfo> studentWrapper = new QueryWrapper<>();
                studentWrapper.lambda().eq(SmsStudentInfo::getStuNo, smsStudentInfo.getStuNo());
                List<SmsStudentInfo> studentInfoList = smsStudentInfoMapper.selectList(studentWrapper);
                if (studentInfoList != null && studentInfoList.size() > 0) {
                    update_add_flag = false;
                }
                if (update_add_flag) {
                    smsStudentInfoMapper.insert(smsStudentInfo);
                    if (isNullOrEmpty(smsStudentInfo.getId())) {
                        // 手动回滚事务
                        transactionManager.rollback(status);
                        createTeacherImportTaskDetail(smsStudentInfo.getStuNo(), smsStudentInfo.getStuName(), task_id, REASON_FAIL, (i + OFFSET_ROW) + "");
                        task_status = TASK_STATUS_ERR;
                        continue;
                    }
                    student_id = smsStudentInfo.getId();
                } else {
                    smsStudentInfoMapper.update(smsStudentInfo, studentWrapper);
                    student_id = studentInfoList.get(0).getId();
                }

                boolean is_user_exist = false;
                //用户信息添加
                QueryWrapper<SmsUser> userWrapper = new QueryWrapper<>();
                userWrapper.lambda().eq(SmsUser::getUsername, smsStudentInfo.getStuNo());
                SmsUser smsUser = smsUserMapper.selectOne(userWrapper);
                //TODO 是否需要更新用户信息
                if (smsUser != null) {
                    is_user_exist = true;
                    user_id = smsUser.getId();
                } else {
                    QueryWrapper<SmsUser> telWrapper = new QueryWrapper<>();
                    telWrapper.lambda().eq(SmsUser::getTel, smsStudentInfo.getStuTel());
                    SmsUser telUser = smsUserMapper.selectOne(telWrapper);
                    if (telUser != null) {
                        // 手动回滚事务
                        transactionManager.rollback(status);
                        createTeacherImportTaskDetail(smsStudentInfo.getStuNo(), smsStudentInfo.getStuName(), task_id, REASON_TEL_EXIST, (i + OFFSET_ROW) + "");
                        task_status = TASK_STATUS_ERR;
                        continue;
                    }

                    SmsUser user = new SmsUser();
                    user.setFlag(STUDENT_FLAG);
                    user.setPassword(DEFAULT_PASSWORD);
                    user.setUsername(smsStudentInfo.getStuNo());
                    user.setTel(smsStudentInfo.getStuTel());
                    user.setRealName(smsStudentInfo.getStuName());
                    smsUserMapper.insert(user);
                    user_id = user.getId();
                }

                //学生与用户关系表
                //清除原有关系
                QueryWrapper<SmsUserStudentRelation> relationQueryWrapper = new QueryWrapper<>();
                relationQueryWrapper.lambda().eq(SmsUserStudentRelation::getStuId, student_id)
                        .or().eq(SmsUserStudentRelation::getUserId, user_id);
                smsUserStudentRelationMapper.delete(relationQueryWrapper);

                SmsUserStudentRelation smsUserStudentRelation = new SmsUserStudentRelation();
                smsUserStudentRelation.setUserId(user_id);
                smsUserStudentRelation.setStuId(student_id);
                smsUserStudentRelationMapper.insert(smsUserStudentRelation);

                //用户与组织架构关系表
                //清除已存在关系
                QueryWrapper<SmsOrgUserRelation> deleteWrapper = new QueryWrapper<>();
                deleteWrapper.lambda().eq(SmsOrgUserRelation::getUserId, user_id);
                smsOrgUserRelationMapper.delete(deleteWrapper);

                for (Integer org_id : orgIdList) {
                    SmsOrgUserRelation orgUserRelation = new SmsOrgUserRelation();
                    orgUserRelation.setOrgId(org_id.toString());
                    orgUserRelation.setUserId(user_id);
                    smsOrgUserRelationMapper.insert(orgUserRelation);
                }


                //用户与角色关系表
                //清除已存在关系
//                if (!is_user_exist) {
                QueryWrapper<SmsUserRoleRelation> roleWrapper = new QueryWrapper<>();
                roleWrapper.lambda().eq(SmsUserRoleRelation::getUserId, user_id);
                smsUserRoleRelationMapper.delete(roleWrapper);

                SmsUserRoleRelation roleRelation = new SmsUserRoleRelation();
                roleRelation.setRoleId(ROLE_STUDENT + "");
                roleRelation.setUserId(user_id);
                smsUserRoleRelationMapper.insert(roleRelation);
//                }

                // 手动提交事务
                transactionManager.commit(status);
            } catch (Exception e) {
                e.printStackTrace();
                // 手动回滚事务
                transactionManager.rollback(status);
            }
        }
        SmsImportTask smsImportTask = new SmsImportTask();
        smsImportTask.setId(task_id);
        smsImportTask.setStatus(task_status);
        smsImportTaskMapper.updateById(smsImportTask);

    }

    private void createTeacherImportTaskDetail(String no, String name, String task_id, String reason, String row) {
        SmsImportTaskDetail smsImportTaskDetail = new SmsImportTaskDetail();
        smsImportTaskDetail.setTaskId(task_id);
        smsImportTaskDetail.setFailReason(reason);
        smsImportTaskDetail.setFailName(name);
        smsImportTaskDetail.setFailNo(no);
        smsImportTaskDetail.setFailRow(row);
        smsImportTaskDetailMapper.insert(smsImportTaskDetail);
    }


    @Override
    @Transactional
    public ResponseResult addStudentInfo(SmsStudentInfoReq smsStudentInfoReq) {
        if (isNullOrEmpty(smsStudentInfoReq.getStuNo()) || isNullOrEmpty(smsStudentInfoReq.getStuName())
                || isNullOrEmpty(smsStudentInfoReq.getStuTel()) || isNullOrEmpty(smsStudentInfoReq.getStuCollege())
                || isNullOrEmpty(smsStudentInfoReq.getStuMajor()) || isNullOrEmpty(smsStudentInfoReq.getStuGrade())
                || isNullOrEmpty(smsStudentInfoReq.getStuClass())) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }
        List<Integer> orgIdList = new ArrayList<>();
        SmsStudentInfo smsStudentInfo = new SmsStudentInfo();

        BeanUtils.copyProperties(smsStudentInfoReq, smsStudentInfo);

        QueryWrapper<SmsOrgStructure> orgWrapper = new QueryWrapper<>();
        List<SmsOrgStructure> orgList = smsOrgStructureMapper.selectList(orgWrapper);
        orgWrapper.lambda().eq(SmsOrgStructure::getOrgName, smsStudentInfo.getStuCollege());
        SmsOrgStructure collegeOrg = smsOrgStructureMapper.selectOne(orgWrapper);
        if (collegeOrg == null) {
            return CommonResult.failed(CommonCodeEnum.REASON_ORG_COLLEGE_NOT_EXIST);
        }
        List<Node> nodeList = new ArrayList<>();
        for (SmsOrgStructure structure : orgList) {
            Node node = new Node();
            BeanUtils.copyProperties(structure, node);
            nodeList.add(node);
        }
        Node collegeNode = nodeTreeUtil.getChildNodesTree(nodeList, collegeOrg.getId());
        List<Node> childNode = collegeNode.getChildNodeList();
        List<Node> majorNode = childNode.stream()
                .filter(node -> node.getOrgName().equals(smsStudentInfo.getStuMajor()))
                .collect(Collectors.toList());
        if (majorNode.size() < 1) {
            return CommonResult.failed(CommonCodeEnum.REASON_ORG_MAJOR_NOT_EXIST);
        }
        List<Node> gradeNode = majorNode.get(0).getChildNodeList().stream()
                .filter(node -> node.getOrgName().equals(smsStudentInfo.getStuGrade()))
                .collect(Collectors.toList());
        if (gradeNode.size() < 1) {
            return CommonResult.failed(CommonCodeEnum.REASON_ORG_GRADE_NOT_EXIST);
        }
        List<Node> classNode = gradeNode.get(0).getChildNodeList().stream()
                .filter(node -> node.getOrgName().equals(smsStudentInfo.getStuClass()))
                .collect(Collectors.toList());
        if (classNode.size() < 1) {
            return CommonResult.failed(CommonCodeEnum.REASON_ORG_CLASS_NOT_EXIST);
        }
        orgIdList.add(classNode.get(0).getId());

        String student_id;
        String user_id = null;

        //工号验证 学生更新 添加
        QueryWrapper<SmsStudentInfo> studentWrapper = new QueryWrapper<>();
        studentWrapper.lambda().eq(SmsStudentInfo::getStuNo, smsStudentInfo.getStuNo());
        List<SmsStudentInfo> studentInfoList = smsStudentInfoMapper.selectList(studentWrapper);
        if (studentInfoList != null && studentInfoList.size() > 0) {
            ExceptionCast.cast(CommonResult.failed(CommonCodeEnum.STUDENT_EXIST));
        }
        smsStudentInfoMapper.insert(smsStudentInfo);
        if (isNullOrEmpty(smsStudentInfo.getId())) {
            ExceptionCast.cast(CommonResult.failed(CommonCodeEnum.FAIL));
        }
        student_id = smsStudentInfo.getId();

        //用户信息添加
        QueryWrapper<SmsUser> userWrapper = new QueryWrapper<>();
        userWrapper.lambda().eq(SmsUser::getUsername, smsStudentInfo.getStuNo());
        SmsUser smsUser = smsUserMapper.selectOne(userWrapper);
        //TODO 是否需要更新用户信息
        if (smsUser != null) {
            ExceptionCast.cast(CommonResult.failed(CommonCodeEnum.USER_ACCOUNT_EXIST));
        } else {
            QueryWrapper<SmsUser> telWrapper = new QueryWrapper<>();
            telWrapper.lambda().eq(SmsUser::getTel, smsStudentInfo.getStuTel());
            SmsUser telUser = smsUserMapper.selectOne(telWrapper);
            if (telUser != null) {
                ExceptionCast.cast(CommonResult.failed(CommonCodeEnum.TEL_EXIST));
            }

            SmsUser user = new SmsUser();
            user.setFlag(STUDENT_FLAG);
            user.setPassword(DEFAULT_PASSWORD);
            user.setUsername(smsStudentInfo.getStuNo());
            user.setTel(smsStudentInfo.getStuTel());
            user.setRealName(smsStudentInfo.getStuName());
            smsUserMapper.insert(user);
            user_id = user.getId();
            if (user_id == null) {
                ExceptionCast.cast(CommonResult.failed(CommonCodeEnum.FAIL));
            }
        }

        //学生与用户关系表
        //清除原有关系
        QueryWrapper<SmsUserStudentRelation> relationQueryWrapper = new QueryWrapper<>();
        relationQueryWrapper.lambda().eq(SmsUserStudentRelation::getStuId, student_id)
                .or().eq(SmsUserStudentRelation::getUserId, user_id);
        smsUserStudentRelationMapper.delete(relationQueryWrapper);

        SmsUserStudentRelation smsUserStudentRelation = new SmsUserStudentRelation();
        smsUserStudentRelation.setUserId(user_id);
        smsUserStudentRelation.setStuId(student_id);
        smsUserStudentRelationMapper.insert(smsUserStudentRelation);

        //用户与组织架构关系表
        //清除已存在关系
        QueryWrapper<SmsOrgUserRelation> deleteWrapper = new QueryWrapper<>();
        deleteWrapper.lambda().eq(SmsOrgUserRelation::getUserId, user_id);
        smsOrgUserRelationMapper.delete(deleteWrapper);

        for (Integer org_id : orgIdList) {
            SmsOrgUserRelation orgUserRelation = new SmsOrgUserRelation();
            orgUserRelation.setOrgId(org_id.toString());
            orgUserRelation.setUserId(user_id);
            smsOrgUserRelationMapper.insert(orgUserRelation);
        }


        //用户与角色关系表
        //清除已存在关系
        QueryWrapper<SmsUserRoleRelation> roleWrapper = new QueryWrapper<>();
        roleWrapper.lambda().eq(SmsUserRoleRelation::getUserId, user_id);
        smsUserRoleRelationMapper.delete(roleWrapper);

        SmsUserRoleRelation roleRelation = new SmsUserRoleRelation();
        roleRelation.setRoleId(ROLE_STUDENT + "");
        roleRelation.setUserId(user_id);
        smsUserRoleRelationMapper.insert(roleRelation);

        return CommonResult.success();
    }

    @Override
    public ResponseResult getOrgTree() {
        List<SmsOrgStructure> orgStructures = smsOrgStructureMapper.selectList(new QueryWrapper<>());
        List<SmsOrgStructureResp> orgStructureRespList = new ArrayList<>();
        if (orgStructures != null && orgStructures.size() > 0) {
            for (SmsOrgStructure smsOrgStructure : orgStructures) {
                SmsOrgStructureResp resp = new SmsOrgStructureResp();
                BeanUtils.copyProperties(smsOrgStructure, resp);
                orgStructureRespList.add(resp);
            }
        }
        List<OrgNode> orgNodes = orgStructureRespList.stream()
                .filter(org -> org.getOrgName().equals(ORG_NAME_COLLAGE))
                .map(org -> covertOrgNode(org, orgStructureRespList))
                .collect(Collectors.toList());
        return CommonResult.success(orgNodes);
    }

    private OrgNode covertOrgNode(SmsOrgStructureResp menu, List<SmsOrgStructureResp> menuList) {
        OrgNode node = new OrgNode();
        BeanUtils.copyProperties(menu, node);
        List<OrgNode> children = menuList.stream()
                .filter(subMenu -> subMenu.getParentId()
                        .equals(menu.getId()))
                .map(subMenu -> covertOrgNode(subMenu, menuList))
                .collect(Collectors.toList());
        node.setChildren(children);
        return node;
    }


    @Override
    public ResponseResult getStudentInfoList(Integer org_id, String stuCollage, String stuMajor, String stuGrade,
                                             String stuClass, Integer stuStatus, String searchStr, Integer pageNum, Integer pageSize) {
        SmsOrgStructure orgStructure;
        if (org_id != null) {
            orgStructure = smsOrgStructureMapper.selectById(org_id);
            if (orgStructure == null) {
                return CommonResult.failed(CommonCodeEnum.ORG_NOT_EXIST);
            }
        }

        List<SmsStudentInfoSimpleResp> respList = new ArrayList<>();
        int total = 0;
        List<String> stuIDList = null;
        if (org_id != null) {
            QueryWrapper<SmsOrgStructure> queryWrapper = new QueryWrapper<>();
            List<SmsOrgStructure> list = smsOrgStructureMapper.selectList(queryWrapper);
            List<OrgNode> orgNodes = new ArrayList<>();
            for (SmsOrgStructure smsOrgStructure : list) {
                OrgNode orgNode = new OrgNode();
                BeanUtils.copyProperties(smsOrgStructure, orgNode);
                orgNodes.add(orgNode);
            }
            List<Integer> orgList = NodeUtil.getChildNodes(orgNodes, org_id);
            if (orgList == null || orgList.size() < 1) {
                return CommonResult.success(respList,total);
            }

            List<SmsOrgUserRelation> orgUserRelationList = smsOrgUserRelationMapper
                    .selectList(new QueryWrapper<SmsOrgUserRelation>().lambda().in(SmsOrgUserRelation::getOrgId, orgList));
            List<String> userList = orgUserRelationList.stream().map(SmsOrgUserRelation::getUserId).collect(Collectors.toList());
            if (userList.size() < 1) {
                return CommonResult.success(respList,total);
            }

            List<SmsUser> userInfoList = smsUserMapper
                    .selectList(new QueryWrapper<SmsUser>().lambda().in(SmsUser::getId, userList).eq(SmsUser::getFlag, STUDENT_FLAG));
            List<String> userIDList = userInfoList.stream().map(SmsUser::getId).collect(Collectors.toList());
            if (userIDList.size() < 1) {
                return CommonResult.success(respList,total);
            }

            List<SmsUserStudentRelation> userStudentRelationList = smsUserStudentRelationMapper
                    .selectList(new QueryWrapper<SmsUserStudentRelation>().lambda().in(SmsUserStudentRelation::getUserId, userIDList));
            stuIDList = userStudentRelationList.stream().map(SmsUserStudentRelation::getStuId).collect(Collectors.toList());
            if (stuIDList.size() < 1) {
                return CommonResult.success(respList,total);
            }
        }

        Page<SmsStudentInfo> page = new Page<>(pageNum, pageSize);
        QueryWrapper<SmsStudentInfo> studentInfoQueryWrapper = new QueryWrapper<>();
        studentInfoQueryWrapper.lambda().orderByDesc(SmsStudentInfo::getCreateTime);
        if (stuIDList != null && stuIDList.size() > 1) {
            studentInfoQueryWrapper.lambda().in(SmsStudentInfo::getId, stuIDList);
        }
        if (!isNullOrEmpty(stuCollage)) {
            studentInfoQueryWrapper.lambda().eq(SmsStudentInfo::getStuCollege, stuCollage);
        }
        if (!isNullOrEmpty(stuMajor)) {
            studentInfoQueryWrapper.lambda().eq(SmsStudentInfo::getStuMajor, stuMajor);
        }
        if (!isNullOrEmpty(stuGrade)) {
            studentInfoQueryWrapper.lambda().eq(SmsStudentInfo::getStuGrade, stuGrade);
        }
        if (!isNullOrEmpty(stuClass)) {
            studentInfoQueryWrapper.lambda().eq(SmsStudentInfo::getStuClass, stuClass);
        }
        if (!isNullOrEmpty(stuStatus)) {
            studentInfoQueryWrapper.lambda().eq(SmsStudentInfo::getStuStatus, stuStatus);
        }
        if (!isNullOrEmpty(searchStr)) {
            studentInfoQueryWrapper.lambda().and(smsStudentInfoLambdaQueryWrapper -> smsStudentInfoLambdaQueryWrapper.like(SmsStudentInfo::getStuName, searchStr)
                    .or()
                    .like(SmsStudentInfo::getStuCollege, searchStr)
                    .or()
                    .like(SmsStudentInfo::getStuMajor, searchStr)
                    .or()
                    .like(SmsStudentInfo::getStuGrade, searchStr)
                    .or()
                    .like(SmsStudentInfo::getStuClass, searchStr))
            ;
        }
        smsStudentInfoMapper.selectPage(page, studentInfoQueryWrapper);
        List<SmsStudentInfo> studentInfoList = page.getRecords();
        total = (int) page.getTotal();
        respList = studentInfoList.stream().map(stu -> {
            SmsStudentInfoSimpleResp simpleResp = new SmsStudentInfoSimpleResp();
            BeanUtils.copyProperties(stu, simpleResp);
            return simpleResp;
        }).collect(Collectors.toList());
        return CommonResult.success(respList,total);
    }

    @Override
    public ResponseResult getStudentInfoDetail(String stu_id) {
        if (isNullOrEmpty(stu_id)) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }
        SmsStudentInfo studentInfo = smsStudentInfoMapper.selectById(stu_id);
        if (studentInfo == null) {
            return CommonResult.failed(CommonCodeEnum.STUDENT_NOT_EXIST);
        }
        SmsStudentInfoResp studentInfoResp = new SmsStudentInfoResp();
        BeanUtils.copyProperties(studentInfo, studentInfoResp);
        //家庭成员信息
        String stuParentInfo = studentInfo.getStuParentInfo();
        if (isNullOrEmpty(stuParentInfo)) {
            return CommonResult.success(studentInfoResp);
        }

        List<SmsStudentParentInfoResp> parentInfoList = JSONObject.parseArray(stuParentInfo, SmsStudentParentInfoResp.class);
        studentInfoResp.setStuParentInfo(parentInfoList);

        return CommonResult.success(studentInfoResp);
    }

    @Override
    public ResponseResult getStudentDropBoxContent(Integer org_id) {
        Map<String, Object> map = new HashMap<>();

        List<Integer> orgList = new ArrayList<>();
        if (!isNullOrEmpty(org_id)) {
            QueryWrapper<SmsOrgStructure> queryWrapper = new QueryWrapper<>();
            List<SmsOrgStructure> list = smsOrgStructureMapper.selectList(queryWrapper);
            List<OrgNode> orgNodes = new ArrayList<>();
            for (SmsOrgStructure smsOrgStructure : list) {
                OrgNode orgNode = new OrgNode();
                BeanUtils.copyProperties(smsOrgStructure, orgNode);
                orgNodes.add(orgNode);
            }
            orgList = NodeUtil.getChildNodes(orgNodes, org_id);
            if (orgList.size() < 1) {
                orgList.add(0);
            }
        } else {
            orgList.add(0);
        }

//        List<String> collageList = smsOrgStructureMapper
//                .selectList(new QueryWrapper<SmsOrgStructure>().lambda().eq(SmsOrgStructure::getLevel, ORG_TYPE_COLLEGE).in(SmsOrgStructure::getId,orgList))
//                .stream().map(SmsOrgStructure::getOrgName).collect(Collectors.toList());
//
//        List<String> majorList = smsOrgStructureMapper
//                .selectList(new QueryWrapper<SmsOrgStructure>().lambda().eq(SmsOrgStructure::getLevel, ORG_TYPE_MAJOR).in(SmsOrgStructure::getId,orgList))
//                .stream().map(SmsOrgStructure::getOrgName).collect(Collectors.toList());
//
//        List<String> gradeList = smsOrgStructureMapper
//                .selectList(new QueryWrapper<SmsOrgStructure>().select("DISTINCT org_name").lambda().eq(SmsOrgStructure::getLevel, ORG_TYPE_GRADE).in(SmsOrgStructure::getId,orgList))
//                .stream().map(SmsOrgStructure::getOrgName).collect(Collectors.toList());
//
//        List<String> classList = smsOrgStructureMapper
//                .selectList(new QueryWrapper<SmsOrgStructure>().lambda().eq(SmsOrgStructure::getLevel, ORG_TYPE_CLASS).in(SmsOrgStructure::getId,orgList))
//                .stream().map(SmsOrgStructure::getOrgName).collect(Collectors.toList());

        Map<String, Object> statusMap1 = new HashMap<>();
        statusMap1.put("name", STUDENT_STATUS_NORMAL_STR);
        statusMap1.put("value", STUDENT_STATUS_NORMAL);
        Map<String, Object> statusMap2 = new HashMap<>();
        statusMap2.put("name", STUDENT_STATUS_LEAVE_STR);
        statusMap2.put("value", STUDENT_STATUS_LEAVE);
        Map<String, Object> statusMap3 = new HashMap<>();
        statusMap3.put("name", STUDENT_STATUS_KEEP_STR);
        statusMap3.put("value", STUDENT_STATUS_KEEP);
        List<Map<String, Object>> statusList = new ArrayList<>();
        statusList.add(statusMap1);
        statusList.add(statusMap2);
        statusList.add(statusMap3);

//        map.put("collageList", collageList);
//        map.put("majorList", majorList);
//        map.put("gradeList", gradeList);
//        map.put("classList", classList);
        map.put("statusList", statusList);
        return CommonResult.success(map);
    }

    @Override
    public ResponseResult getAddStudentDropBoxContent(Integer type, Integer id) {
        if (isNullOrEmpty(type)) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }
        if (type != ORG_TYPE_COLLEGE && isNullOrEmpty(id)) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }
        List<Map<String, Object>> resultList;
        switch (type) {
            case ORG_TYPE_COLLEGE:
                resultList = smsOrgStructureMapper
                        .selectList(new QueryWrapper<SmsOrgStructure>().lambda().eq(SmsOrgStructure::getLevel, ORG_TYPE_COLLEGE))
                        .stream().map(smsOrgStructure -> {
                            Map<String, Object> map = new HashMap<>();
                            map.put("name", smsOrgStructure.getOrgName());
                            map.put("id", smsOrgStructure.getId());
                            return map;
                        }).collect(Collectors.toList());
                break;
            case ORG_TYPE_MAJOR:
                resultList = smsOrgStructureMapper
                        .selectList(new QueryWrapper<SmsOrgStructure>().lambda().eq(SmsOrgStructure::getLevel, ORG_TYPE_MAJOR).eq(SmsOrgStructure::getParentId, id))
                        .stream().map(smsOrgStructure -> {
                            Map<String, Object> map = new HashMap<>();
                            map.put("name", smsOrgStructure.getOrgName());
                            map.put("id", smsOrgStructure.getId());
                            return map;
                        }).collect(Collectors.toList());
                break;
            case ORG_TYPE_GRADE:
                resultList = smsOrgStructureMapper
                        .selectList(new QueryWrapper<SmsOrgStructure>().lambda().eq(SmsOrgStructure::getLevel, ORG_TYPE_GRADE).eq(SmsOrgStructure::getParentId, id))
                        .stream().map(smsOrgStructure -> {
                            Map<String, Object> map = new HashMap<>();
                            map.put("name", smsOrgStructure.getOrgName());
                            map.put("id", smsOrgStructure.getId());
                            return map;
                        }).collect(Collectors.toList());
                break;
            case ORG_TYPE_CLASS:
                resultList = smsOrgStructureMapper
                        .selectList(new QueryWrapper<SmsOrgStructure>().lambda().eq(SmsOrgStructure::getLevel, ORG_TYPE_CLASS).eq(SmsOrgStructure::getParentId, id))
                        .stream().map(smsOrgStructure -> {
                            Map<String, Object> map = new HashMap<>();
                            map.put("name", smsOrgStructure.getOrgName());
                            map.put("id", smsOrgStructure.getId());
                            return map;
                        }).collect(Collectors.toList());
                break;
            default:
                resultList = new ArrayList<>();
        }
        return CommonResult.success(resultList);
    }

    @Override
    @Transactional
    public ResponseResult batchDeleteStudentInfo(Map<String, Object> map) {
        List<String> stuIDList = JSONObject.parseArray(JSON.toJSONString(map.get("list")), String.class);
        if (stuIDList == null || stuIDList.size() < 1) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }

        for (String student_id : stuIDList) {
            //删除学籍
            smsStudentInfoMapper.deleteById(student_id);

            QueryWrapper<SmsUserStudentRelation> userStudentRelationQueryWrapper = new QueryWrapper<>();
            userStudentRelationQueryWrapper.lambda().eq(SmsUserStudentRelation::getStuId, student_id);
            SmsUserStudentRelation studentRelation = smsUserStudentRelationMapper.selectOne(userStudentRelationQueryWrapper);
            if (studentRelation == null) {
                continue;
            }
            String user_id = studentRelation.getUserId();

            //删除用户
            smsUserMapper.deleteById(user_id);

            //学生与用户关系表
            //清除原有关系
            QueryWrapper<SmsUserStudentRelation> relationQueryWrapper = new QueryWrapper<>();
            relationQueryWrapper.lambda().eq(SmsUserStudentRelation::getStuId, student_id)
                    .or().eq(SmsUserStudentRelation::getUserId, user_id);
            smsUserStudentRelationMapper.delete(relationQueryWrapper);

            //用户与组织架构关系表
            //清除已存在关系
            QueryWrapper<SmsOrgUserRelation> deleteWrapper = new QueryWrapper<>();
            deleteWrapper.lambda().eq(SmsOrgUserRelation::getUserId, user_id);
            smsOrgUserRelationMapper.delete(deleteWrapper);


            //用户与角色关系表
            //清除已存在关系
            QueryWrapper<SmsUserRoleRelation> roleWrapper = new QueryWrapper<>();
            roleWrapper.lambda().eq(SmsUserRoleRelation::getUserId, user_id);
            smsUserRoleRelationMapper.delete(roleWrapper);
        }
        return CommonResult.success();
    }

    @Override
    public ResponseResult updateStudentInfo(SmsStudentInfoReq smsStudentInfoReq) {
        if (isNullOrEmpty(smsStudentInfoReq.getId())) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }
        SmsStudentInfo studentInfo = smsStudentInfoMapper.selectById(smsStudentInfoReq.getId());
        if (studentInfo == null) {
            return CommonResult.failed(CommonCodeEnum.STUDENT_NOT_EXIST);
        }

        SmsStudentInfo smsStudentInfo = new SmsStudentInfo();
        BeanUtils.copyProperties(smsStudentInfoReq, smsStudentInfo);
        //家庭成员信息
        List<SmsStudentParentInfoReq> stuParentInfo = smsStudentInfoReq.getStuParentInfo();
        if (!isNullOrEmpty(stuParentInfo)) {
            String stuParentInfoStr = JSONObject.parseObject(JSON.toJSONString(stuParentInfo), String.class);
            smsStudentInfo.setStuParentInfo(stuParentInfoStr);
        }
        int result = smsStudentInfoMapper.updateById(smsStudentInfo);
        if (result == 0) {
            return CommonResult.failed(CommonCodeEnum.UPDATE_FAIL);
        }
        return CommonResult.success();
    }

    @Override
    @Async
    public Future<String> exportStudentInfo(SmsStudentExportReq smsStudentExportReq, HttpServletResponse response) {
        try {
            List<SmsStudentInfoSimpleResp> respList = new ArrayList<>();
            int total = 0;
            List<String> stuIDList = null;
            Integer org_id = smsStudentExportReq.getOrg_id();
            if (org_id != null) {
                QueryWrapper<SmsOrgStructure> queryWrapper = new QueryWrapper<>();
                List<SmsOrgStructure> list = smsOrgStructureMapper.selectList(queryWrapper);
                List<OrgNode> orgNodes = new ArrayList<>();
                for (SmsOrgStructure smsOrgStructure : list) {
                    OrgNode orgNode = new OrgNode();
                    BeanUtils.copyProperties(smsOrgStructure, orgNode);
                    orgNodes.add(orgNode);
                }
                List<Integer> orgList = NodeUtil.getChildNodes(orgNodes, org_id);
                if (orgList == null || orgList.size() < 1) {
                    return null;
                }

                List<SmsOrgUserRelation> orgUserRelationList = smsOrgUserRelationMapper
                        .selectList(new QueryWrapper<SmsOrgUserRelation>().lambda().in(SmsOrgUserRelation::getOrgId, orgList));
                List<String> userList = orgUserRelationList.stream().map(SmsOrgUserRelation::getUserId).collect(Collectors.toList());
                if (userList.size() < 1) {
                    return null;
                }

                List<SmsUser> userInfoList = smsUserMapper
                        .selectList(new QueryWrapper<SmsUser>().lambda().in(SmsUser::getId, userList).eq(SmsUser::getFlag, STUDENT_FLAG));
                List<String> userIDList = userInfoList.stream().map(SmsUser::getId).collect(Collectors.toList());
                if (userIDList.size() < 1) {
                    return null;
                }

                List<SmsUserStudentRelation> userStudentRelationList = smsUserStudentRelationMapper
                        .selectList(new QueryWrapper<SmsUserStudentRelation>().lambda().in(SmsUserStudentRelation::getUserId, userIDList));
                stuIDList = userStudentRelationList.stream().map(SmsUserStudentRelation::getStuId).collect(Collectors.toList());
                if (stuIDList.size() < 1) {
                    return null;
                }
            }

            QueryWrapper<SmsStudentInfo> studentInfoQueryWrapper = new QueryWrapper<>();
            studentInfoQueryWrapper.lambda().orderByDesc(SmsStudentInfo::getCreateTime);
            if (stuIDList != null && stuIDList.size() > 1) {
                studentInfoQueryWrapper.lambda().in(SmsStudentInfo::getId, stuIDList);
            }
            if (!isNullOrEmpty(smsStudentExportReq.getStuCollege())) {
                studentInfoQueryWrapper.lambda().eq(SmsStudentInfo::getStuCollege, smsStudentExportReq.getStuCollege());
            }
            if (!isNullOrEmpty(smsStudentExportReq.getStuMajor())) {
                studentInfoQueryWrapper.lambda().eq(SmsStudentInfo::getStuMajor, smsStudentExportReq.getStuMajor());
            }
            if (!isNullOrEmpty(smsStudentExportReq.getStuGrade())) {
                studentInfoQueryWrapper.lambda().eq(SmsStudentInfo::getStuGrade, smsStudentExportReq.getStuGrade());
            }
            if (!isNullOrEmpty(smsStudentExportReq.getStuClass())) {
                studentInfoQueryWrapper.lambda().eq(SmsStudentInfo::getStuClass, smsStudentExportReq.getStuClass());
            }
            if (!isNullOrEmpty(smsStudentExportReq.getStuStatus())) {
                studentInfoQueryWrapper.lambda().eq(SmsStudentInfo::getStuStatus, smsStudentExportReq.getStuStatus());
            }
            if (!isNullOrEmpty(smsStudentExportReq.getSearchStr())) {
                String searchStr = smsStudentExportReq.getSearchStr();
                studentInfoQueryWrapper.lambda().and(smsStudentInfoLambdaQueryWrapper -> smsStudentInfoLambdaQueryWrapper.like(SmsStudentInfo::getStuName, searchStr)
                        .or()
                        .like(SmsStudentInfo::getStuCollege, searchStr)
                        .or()
                        .like(SmsStudentInfo::getStuMajor, searchStr)
                        .or()
                        .like(SmsStudentInfo::getStuGrade, searchStr)
                        .or()
                        .like(SmsStudentInfo::getStuClass, searchStr));
            }
            List<SmsStudentInfo> list = smsStudentInfoMapper.selectList(studentInfoQueryWrapper);
            //表头数据
            String[] header = smsStudentExportReq.getLimitColumn().toArray(new String[0]);
            double sheetNum;
            //声明一个工作簿
            HSSFWorkbook workbook = new HSSFWorkbook();
            if (list != null && list.size() > 0) {
                sheetNum = Math.ceil((double) list.size() / PER_SHEET_NUM);
                for (int k = 0; k < sheetNum; k++) {
                    //生成一个表格，设置表格名称为"资源导出表"
                    HSSFSheet sheet = workbook.createSheet("资源导出表" + (k + 1));

                    //设置表格列宽度为10个字节
                    sheet.setDefaultColumnWidth(12);
                    //创建标题的显示样式
                    HSSFCellStyle headerStyle = workbook.createCellStyle();
                    headerStyle.setFillForegroundColor(IndexedColors.YELLOW.index);
                    headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);

                    HSSFFont f = workbook.createFont();
                    f.setFontHeightInPoints((short) 10);//字号
                    f.setBold(true);//加粗
                    headerStyle.setFont(f);
                    //创建第一行表头
                    HSSFRow headrow = sheet.createRow(0);

                    //遍历添加表头(下面模拟遍历学生，也是同样的操作过程)
                    for (int i = 0; i < header.length + 1; i++) {
                        //创建一个单元格
                        HSSFCell cell = headrow.createCell(i);

                        if (i == 0) {
                            //创建一个内容对象
                            HSSFRichTextString text = new HSSFRichTextString("序号");
                            //将内容对象的文字内容写入到单元格中
                            cell.setCellValue(text);
                            cell.setCellStyle(headerStyle);
                            continue;
                        }
                        //创建一个内容对象
                        String header1 = apiModelUtil.getFieldValueByFieldName(SmsStudentInfo.class, header[i - 1]);
                        HSSFRichTextString text = new HSSFRichTextString(header1);

                        //将内容对象的文字内容写入到单元格中
                        cell.setCellValue(text);
                        cell.setCellStyle(headerStyle);
                    }

                    int range = PER_SHEET_NUM;
                    if (k + 1 == sheetNum) {
                        range = list.size() - (PER_SHEET_NUM) * k;
                    }
                    for (int i = 0; i < range; i++) {
                        //创建一行
                        HSSFRow row1 = sheet.createRow(i + 1);
                        SmsStudentInfo getsummary = list.get((PER_SHEET_NUM) * k + i);
                        Map map = JSONObject.parseObject(JSON.toJSONString(getsummary), Map.class);
                        row1.createCell(0).setCellValue(new HSSFRichTextString(i + 1 + ""));
                        for (int j = 0; j < header.length; j++) {
                            String rowContent = "";
                            if (map.get(header[j]) instanceof Long){
                                rowContent = TimeUtil.DateformatTimestamp((long)map.get(header[j]));
                            }else{
                                rowContent = (String) map.get(header[j]);
                            }
                            row1.createCell(j + 1).setCellValue(new HSSFRichTextString(rowContent));
                        }

                    }
                }
            }
//            response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
            response.setContentType("application/vnd.ms-excel");
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("学籍信息导出表.xlsx", "utf-8"));
            response.setHeader("file-type","download");
            response.setHeader("file-name", URLEncoder.encode("学籍信息导出表.xlsx", "utf-8"));
            response.setHeader("Access-Control-Expose-Headers", "file-type,file-name");
            //刷新缓冲
            response.flushBuffer();
            //workbook将Excel写入到response的输出流中，供页面下载
            workbook.write(response.getOutputStream());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


    @Autowired
    FreeMarkerConfigurer freeMarkerConfigurer;

    @Override
    public ResponseResult exportStudentStatus(String user_id, HttpServletRequest request, HttpServletResponse response) {
        try {
            QueryWrapper<SmsUserStudentRelation> studentRelationQueryWrapper = new QueryWrapper<>();
            studentRelationQueryWrapper.lambda().eq(SmsUserStudentRelation::getUserId, user_id);
            SmsUserStudentRelation studentRelation = smsUserStudentRelationMapper.selectOne(studentRelationQueryWrapper);
            if (studentRelation == null) {
                return CommonResult.failed(CommonCodeEnum.STUDENT_NOT_EXIST);
            }

            SmsStudentInfo studentInfo = cacheUtil.getTeacherOrStudentInfo(studentRelation.getStuId(), 1, SmsStudentInfo.class);
            if (studentInfo == null) {
                return CommonResult.failed(CommonCodeEnum.STUDENT_NOT_EXIST);
            }

            SmsStudentInfoResp studentInfoResp = new SmsStudentInfoResp();
            BeanUtils.copyProperties(studentInfo, studentInfoResp);

            Map<String, Object> dataMap = new HashMap<>();
            dataMap.put("name", studentInfo.getStuName() == null ? "NAME_NULL" : studentInfo.getStuName());
            dataMap.put("idCard", studentInfo.getStuIdCard() == null ? "ID_CARD_NULL" : studentInfo.getStuIdCard());
            dataMap.put("birth", studentInfo.getStuBirth() == null ? "BIRTH_NULL" : TimeUtil.DateSimpleformat(studentInfo.getStuBirth()));
            dataMap.put("test", "123456");
            dataMap.put("stuNo", studentInfo.getStuNo() == null ? "STU_NO_NULL" : studentInfo.getStuNo());
            dataMap.put("qrcode", QrUtil.crateQRCode("1234466", 100, 100));
            Configuration configuration = new Configuration(Configuration.getVersion());
            configuration.setDefaultEncoding("utf-8");
            Template template = freeMarkerConfigurer.getConfiguration().getTemplate("ssprove.ftl", "utf-8");
            Writer out = new BufferedWriter(new OutputStreamWriter(response.getOutputStream(),
                    StandardCharsets.UTF_8), 10240);
            response.setHeader("file-type", "msw");
            response.setHeader("msw-name", URLEncoder.encode("学籍证明_"+studentInfo.getStuName()+".docx"));
            response.setHeader("content-Type", "application/msword");
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("学籍证明_"+studentInfo.getStuName()+".docx", "utf-8"));
            response.setHeader("Access-Control-Expose-Headers", "file-type,msw-name");
            response.flushBuffer();
            template.process(dataMap, out);
            out.flush();
            out.close();
            return null;
        } catch (Exception e) {
            e.printStackTrace();
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }
    }
}
